package cn.ric.mycurd.plugin;

import java.lang.reflect.Modifier;

import org.apache.ibatis.jdbc.SQL;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

/**
 * @author ric.zhang
 * @date 2021/1/18
 */
class MysqlBuilder extends BaseSqlBuilder {
    @Override
    String buildListAllFieldSql(Class<?> poClass, String[] whereJavaFieldNames, String[] orderJavaFieldNames) {
        SQL sqlBuilder = new SQL();
        final String tableName = getTableName(poClass);
        sqlBuilder.FROM('`' + tableName + '`');
        ReflectionUtils.doWithFields(poClass, (field) -> {
            // 忽略静态属性
            if (Modifier.isStatic(field.getModifiers())) {
                return;
            }
            String columnName = getColumnName(poClass, field.getName());
            if (StringUtils.isEmpty(columnName)) {
                return;
            }
            sqlBuilder.SELECT(String.format("`%s` AS '%s'", columnName, field.getName()));
        });
        int i = 0;
        for (; i < whereJavaFieldNames.length; i++) {
            String fieldName = whereJavaFieldNames[i];
            sqlBuilder.WHERE(String.format("`%s` = #{param%d}", getColumnName(poClass, fieldName), i + 1));
        }
        if (orderJavaFieldNames != null) {
            for (String orderJavaFieldName : orderJavaFieldNames) {
                boolean isDesc;
                String fieldName;
                if (orderJavaFieldName.toLowerCase().endsWith("desc")) {
                    isDesc = true;
                    fieldName = orderJavaFieldName.substring(0, orderJavaFieldName.length() - 4);
                } else if (orderJavaFieldName.toLowerCase().endsWith("asc")) {
                    isDesc = false;
                    fieldName = orderJavaFieldName.substring(0, orderJavaFieldName.length() - 3);
                } else {
                    isDesc = false;
                    fieldName = orderJavaFieldName;
                }
                sqlBuilder.ORDER_BY(fieldName + (isDesc ? " DESC" : " ASC"));
            }
        }
        sqlBuilder.OFFSET(String.format("#{param%d}", i + 1));
        sqlBuilder.LIMIT(String.format("#{param%d}", i + 2));
        return sqlBuilder.toString();
    }

    @Override
    String buildListSomeFieldsSql(Class<?> poClass, String[] whereJavaFieldNames, String[] selectJavaFieldNames,
        String[] orderJavaFieldNames) {
        SQL sqlBuilder = new SQL();
        final String tableName = getTableName(poClass);
        sqlBuilder.FROM('`' + tableName + '`');
        for (String fieldName : selectJavaFieldNames) {
            sqlBuilder.SELECT(
                    String.format("`%s` AS '%s'", getColumnName(poClass, fieldName), getJavaFieldName(poClass, fieldName)));
        }
        int i = 0;
        for (; i < whereJavaFieldNames.length; i++) {
            sqlBuilder.WHERE(String.format("`%s` = #{param%d}", getColumnName(poClass, whereJavaFieldNames[i]), i + 1));
        }
        if (orderJavaFieldNames != null) {
            for (String orderJavaFieldName : orderJavaFieldNames) {
                boolean isDesc;
                String fieldName;
                if (orderJavaFieldName.toLowerCase().endsWith("desc")) {
                    isDesc = true;
                    fieldName = orderJavaFieldName.substring(0, orderJavaFieldName.length() - 4);
                } else if (orderJavaFieldName.toLowerCase().endsWith("asc")) {
                    isDesc = false;
                    fieldName = orderJavaFieldName.substring(0, orderJavaFieldName.length() - 3);
                } else {
                    isDesc = false;
                    fieldName = orderJavaFieldName;
                }
                sqlBuilder.ORDER_BY(fieldName + (isDesc ? " DESC" : " ASC"));
            }
        }
        sqlBuilder.OFFSET(String.format("#{param%d}", i + 1));
        sqlBuilder.LIMIT(String.format("#{param%d}", i + 2));
        return sqlBuilder.toString();
    }
}
